package com.dimples.dd.system.mapper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.dimples.dd.mybatis.core.mapper.BaseMapperX;
import com.dimples.dd.mybatis.core.query.LambdaQueryWrapperX;
import com.dimples.dd.mybatis.core.query.MPJLambdaWrapperX;
import com.dimples.dd.system.core.enums.MenuTypeEnum;
import com.dimples.dd.system.model.bo.RouteBO;
import com.dimples.dd.system.model.bo.SimpleMenuBO;
import com.dimples.dd.system.model.entity.*;
import com.dimples.dd.system.model.query.MenuPageQuery;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;


@Mapper
public interface SystemMenuMapper extends BaseMapperX<SystemMenuDO> {

    /**
     * 根据用户名获取权限集合
     *
     * @param username 用户名
     * @return {@link SystemMenuDO}
     */
    default List<SystemMenuDO> findUserPermissions(String username) {
        MPJLambdaWrapperX<SystemMenuDO> wrapperX = new MPJLambdaWrapperX<>();
        wrapperX.select(SystemMenuDO::getPermission)
                .leftJoin(SystemRoleMenuDO.class, SystemRoleMenuDO::getMenuId, SystemMenuDO::getId)
                .leftJoin(SystemRoleDO.class, SystemRoleDO::getId, SystemRoleMenuDO::getRoleId)
                .leftJoin(SystemUserRoleDO.class, SystemUserRoleDO::getRoleId, SystemRoleDO::getId)
                .leftJoin(SystemUsersDO.class, SystemUsersDO::getId, SystemUserRoleDO::getUserId)
        ;
        wrapperX.isNotNull(SystemMenuDO::getPermission).ne(SystemMenuDO::getPermission, "");
        if (StrUtil.isNotBlank(username)) {
            wrapperX.eq(SystemUsersDO::getUsername, username);
        }
        return this.selectJoinList(SystemMenuDO.class, wrapperX);
    }

    /**
     * 获取路由列表
     *
     * @param userId 用户编号
     * @return {@link List<RouteBO>}
     */
    default List<RouteBO> listRoutes(Long userId) {
        MPJLambdaWrapperX<SystemMenuDO> wrapperX = new MPJLambdaWrapperX<>();
        wrapperX
                .select(SystemMenuDO::getId)
                .selectAs(SystemMenuDO::getMenuName, RouteBO::getName)
                .select(SystemMenuDO::getParentId)
                .selectAs(SystemMenuDO::getRoutePath, RouteBO::getPath)
                .select(SystemMenuDO::getComponent)
                .select(SystemMenuDO::getRouteName)
                .select(SystemMenuDO::getIcon)
                .select(SystemMenuDO::getSort)
                .select(SystemMenuDO::getHideInMenu)
                .selectAs(SystemMenuDO::getMenuType, RouteBO::getType)
                .select(SystemMenuDO::getAlwaysShow)
                .select(SystemMenuDO::getKeepAlive)
                .select(SystemMenuDO::getHref)
                .select(SystemMenuDO::getHrefOpenType)
                .select(SystemMenuDO::getActiveMenu)
                .select(SystemMenuDO::getMultiTab)
                .select(SystemMenuDO::getFixedIndexInTab)
                .select(SystemMenuDO::getI18nKey)
                .selectCollection(SystemRoleDO.class, RouteBO::getRoles, map -> map.result(SystemRoleDO::getCode))

                .leftJoin(SystemRoleMenuDO.class, SystemRoleMenuDO::getMenuId, SystemMenuDO::getId)
                .leftJoin(SystemRoleDO.class, SystemRoleDO::getId, SystemRoleMenuDO::getRoleId)
                .leftJoin(SystemUserRoleDO.class, SystemUserRoleDO::getRoleId, SystemRoleDO::getId);
        wrapperX
                .eq(SystemUserRoleDO::getUserId, userId)
                .ne(SystemMenuDO::getMenuType, MenuTypeEnum.BUTTON.getValue())
                .orderByAsc(SystemMenuDO::getSort);
        return this.selectJoinList(RouteBO.class, wrapperX);
    }

    /**
     * 路由是否存在
     *
     * @param routeName {@link String}
     * @return {@link Boolean}
     */
    default Boolean existRoute(String routeName) {
        LambdaQueryWrapperX<SystemMenuDO> wrapperX = new LambdaQueryWrapperX<>();
        wrapperX.eqIfPresent(SystemMenuDO::getRouteName, routeName);
        return CollUtil.isNotEmpty(this.selectList(wrapperX));
    }

    default SystemMenuDO selectByParentIdAndName(Long parentId, String name) {
        return this.selectOne(SystemMenuDO::getParentId, parentId, SystemMenuDO::getMenuName, name);
    }

    default Long selectCountByParentId(Long parentId) {
        return this.selectCount(SystemMenuDO::getParentId, parentId);
    }

    /**
     * 根据用户id查询菜单信息
     *
     * @param userId 用户id
     * @return 菜单集合
     */
    default List<SystemMenuDO> selectMenuListByUserId(Long userId) {
        MPJLambdaWrapperX<SystemMenuDO> wrapperX = new MPJLambdaWrapperX<>();
        wrapperX.selectAll(SystemMenuDO.class)
                .leftJoin(SystemRoleMenuDO.class, SystemRoleMenuDO::getMenuId, SystemMenuDO::getId)
                .leftJoin(SystemRoleDO.class, SystemRoleDO::getId, SystemRoleMenuDO::getRoleId)
                .leftJoin(SystemUserRoleDO.class, SystemUserRoleDO::getRoleId, SystemRoleDO::getId);
        if (ObjectUtil.isNotEmpty(userId)) {
            wrapperX.eq(SystemUserRoleDO::getUserId, userId);
        }
        wrapperX.orderByAsc(SystemMenuDO::getSort);
        return this.selectJoinList(SystemMenuDO.class, wrapperX);
    }

    default List<SimpleMenuBO> selectSimpleMenu() {
        MPJLambdaWrapperX<SystemMenuDO> wrapperX = new MPJLambdaWrapperX<>();
        wrapperX.select(SystemMenuDO::getId, SystemMenuDO::getMenuName, SystemMenuDO::getParentId, SystemMenuDO::getSort);
        return this.selectJoinList(SimpleMenuBO.class, wrapperX);
    }

    /**
     * 根据参数查询菜单信息
     *
     * @param menuPageQuery 菜单查询参数
     * @return 菜单信息
     */
    default List<SystemMenuDO> selectList(MenuPageQuery menuPageQuery) {
        return selectList(new LambdaQueryWrapperX<SystemMenuDO>()
                .likeIfPresent(SystemMenuDO::getMenuName, menuPageQuery.getMenuName())
                .eqIfPresent(SystemMenuDO::getStatus, menuPageQuery.getStatus())
                .orderByAsc(SystemMenuDO::getSort));
    }
}
























